 /*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.documentar.DAO;

import br.com.documentar.controller.TratadorExecessaoController;
import br.com.documentar.init.CheckBoot;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.swing.JOptionPane;

/**
 * correção da variavel do driver. deve ser apenas uma variavel para facilitar a
 * manutenção e diminiur código
 */
/**
 *
 * @author Santos
 */
public class AbstractDAO {

    private final br.com.documentar.init.CheckBoot checkBoot = new CheckBoot();
    private String driverConnection;
    private String host;
    private String porta;
    private String banco;
    private Statement st;
    private Connection conn;
    ResultSet rs;
    private String url;
    private String usuarioBanco;
    private String senhaBanco;
    public String erroQuery;

    /**
     * Retorna driver de conexão utilizado na conexão com o banco de dados
     *
     * @return
     */
    public String getDriverConnection() {
        return driverConnection;
    }

    /**
     * Informar o nome do driver de conexão que será utilizado para conexão com
     * o banco de dados
     *
     * @param driverConnection Retorna o url do driver de conexão
     */
    public void setDriverConnection(String driverConnection) {
        this.driverConnection = driverConnection;
    }
    /**
     * Nome do banco de dados que será utilizado. Exemplo: Firebird, Oracle,
     * MySql, PostGree
     */
    private String opcaoBancoDados;

    /**
     * Retorna o nome do banco de dados utilizado pelo sistema
     *
     * @return Nome do Banco de Dados
     */
    public String getOpcaoBancoDados() {
        return opcaoBancoDados;
    }

    /**
     * Informar o nome do banco de dados que será utilizado, carregado a partir
     * do arquivo de configuração
     *
     * @param opcaoBancoDados
     */
    public void setOpcaoBancoDados(String opcaoBancoDados) {
        this.opcaoBancoDados = opcaoBancoDados;
    }

    /**
     * Retorna Nome do arquivo de banco de dados que será utilizado.
     *
     * @return
     */
    public String getBanco() {
        return banco;
    }

    /**
     * Informa o nome do arquivo de banco de dados que será utilizado pelo
     * sistema
     *
     * @param banco
     */
    public void setBanco(String banco) {
        this.banco = banco;
    }

    /**
     * Retorna o nome do usuário que será utilizado para acessar o banco de
     * dados
     *
     * @return Nome do usuário
     */
    public String getUsuarioBanco() {
        return usuarioBanco;
    }

    /**
     * Informa o nome do usuário que será utilizado para acessar o banco de
     * dados
     *
     * @param usuarioBanco Nome do usuário
     */
    public void setUsuarioBanco(String usuarioBanco) {
        this.usuarioBanco = usuarioBanco;
    }

    /**
     * Retornar a senha do banco de dados que está sendo utilizada
     *
     * @return Senha do banco de dados
     */
    public String getSenhaBanco() {
        return senhaBanco;
    }

    /**
     * Informar a Senha de acesso ao banco de dados
     *
     * @param senhaBanco Senha de Acesso ao Banco
     */
    public void setSenhaBanco(String senhaBanco) {
        this.senhaBanco = senhaBanco;
    }

    /**
     * Retorna o Host onde está armazenado o banco de dados
     *
     * @return Retorna o Host do Banco de Dados
     */
    public String getHost() {
        return host;
    }

    /**
     * Informa o host onde está o banco de dados
     *
     * @param host Informar o Host do banco de dados
     */
    public void setHost(String host) {
        this.host = host;
    }

    /**
     * Retornar a porta de acesso ao banco de dados
     *
     * @return Retornar a porta de acesso ao banco de dados
     */
    public String getPorta() {
        return porta;
    }

    /**
     * Informa a porta de acesso ao banco de dados
     *
     * @param porta Porta de acesso ao banco de dados
     */
    public void setPorta(String porta) {
        this.porta = porta;
    }

    /**
     * Retorna a url de acesso ao banco de dados
     *
     * @return Retorna URL de acesso ao banco de dados
     */
    public String getUrl() {
        return url;
    }

    /**
     * Informar a url de acesso ao banco de dados
     *
     * @param url Url de acesso ao banco de dados
     */
    public void setUrl(String url) {
        this.url = url;
    }

    /**
     * Metodo construtor. É inicializado quando a classe AbstractDAO é
     * instaceada
     */
    public AbstractDAO() {
        LoadConfig();
    }

    /**
     * Construtor responsável por fazer acesso a qualquer banco de dados em
     * tempo de xecução.
     *
     * @param opcaoBancoDados
     * @param host
     * @param banco
     * @param porta
     * @param usuario
     * @param senha
     */
    public AbstractDAO(String opcaoBancoDados, String host, String banco, String porta, String usuario, String senha) {
        setOpcaoBancoDados(opcaoBancoDados);//alimentar variáveis 
        setHost(host);
        setBanco(banco);
        setPorta(porta);
        setUsuarioBanco(usuario);
        setSenhaBanco(senha);
        UrlConexao(opcaoBancoDados);

    }

    /**
     * Metodo responsável por chamar a leitura do arquivo de configuração para
     * acesso ao banco de dados.
     */
    private void LoadConfig() {
        //faz leitura do arquivo de configuração
        if (checkBoot.ReadFileConnect()) {
            setOpcaoBancoDados(checkBoot.getOpcaoBancoDados());//alimentar variáveis 
            setHost(checkBoot.getHost());
            setBanco(checkBoot.getBanco());
            setPorta(checkBoot.getPorta());
            UrlConexao(getOpcaoBancoDados());
        }
    }

    /**
     * Metodo responsável por montar a URL de conexão para acesso aos bancos de
     * dados
     *
     * @param ConectarBanco Nome do banco de dados que irá se conectar
     */
    public void UrlConexao(String ConectarBanco) {
        switch (ConectarBanco) {
            case "Oracle":
                setUrl("jdbc:oracle:thin:@" + getHost() + ":" + getPorta() + ":" + getBanco() + "");
                setDriverConnection("oracle.jdbc.driver.OracleDriver");
                //  setUsuarioBanco("Documentar");
                //  setSenhaBanco("d0cum3nt@r");
                break;
            case "Firebird":
                setUrl("jdbc:firebirdsql:" + getHost() + "/" + getPorta() + ":" + getBanco() + "");
                setDriverConnection("org.firebirdsql.jdbc.FBDriver");
                setUsuarioBanco("SYSDBA");
                setSenhaBanco("masterkey");
                break;
            case "MySql":
                setUrl("jdbc:mysql://" + getHost() + ":" + getPorta() + "/" + getBanco() + "");
                setDriverConnection("com.mysql.jdbc.Driver");
                setUsuarioBanco("Documentar");
                setSenhaBanco("sNqr258?");
                break;
            case "PostGree":
                setUrl("jdbc:mysql://" + getHost() + ":" + getPorta() + "/" + getBanco() + "");
                setDriverConnection("verificar");
                setUsuarioBanco("root");
                setSenhaBanco("root");
                break;
            default:
                JOptionPane.showMessageDialog(null, "Nenhum banco informado!!!");
                break;
        }
    }

    /**
     * Metodo utilizado para conectar no banco de dados
     *
     * @return True se conectou False se não conectou
     */
    public boolean ConnectDataBase() {
        try {
            Class.forName(getDriverConnection());
            conn = DriverManager.getConnection(getUrl(), getUsuarioBanco(), getSenhaBanco());
            return true;
        } catch (SQLException | ClassNotFoundException | NullPointerException ex) {
            JOptionPane.showMessageDialog(null, ex.getMessage());
            return false;
        }
    }

    /**
     * Metodo responsável por finalizar a conexão com o banco de dados
     *
     * @param nomeTela nome da tela que solicitou fechamento da conexão
     * @return Retorna Treu se teve exito, False se teve erro
     */
    public boolean Desconectar(String nomeTela) {
        try {
            conn.close();
            return true;
        } catch (SQLException | NullPointerException ex) {
            TratadorExecessaoController controlTratamentoErro = new TratadorExecessaoController();
            controlTratamentoErro.setErro(nomeTela, "", ex.getMessage());
            return false;
        }
    }

    /**
     * Metodo responsável por fazer a insert, update e delete no banco de dados
     * e tratar os erros que ocorrem na inserção dos dados
     *
     * @param sql Informar o comando SQL a ser executado
     * @param nomeTela Informar o nome da tela que está fazendo inserção de
     * dados
     * @return Retorna True se funcionou False se deu erro
     *
     */
    public boolean InsertUpdateDelete(String sql, String nomeTela) {
        try {
            //ConnectDataBase(); futuro
            st = conn.createStatement();
            st.executeUpdate(sql);
            st.close();
            return true;
        } catch (SQLException | NullPointerException ex) {
            TratadorExecessaoController controlTratamentoErro = new TratadorExecessaoController();
            controlTratamentoErro.setErro(nomeTela, sql, ex.getMessage());
            return false;
        } finally {
            Desconectar(nomeTela);
        }
    }

    /**
     * Metodo de consulta para tratar os SQL Injection e tratar as excessões que
     * ocorrem nas consultas
     *
     * @param sql script sql para consulta
     * @param nomeTela nome da tela que está fazendo consulta
     * @return ResultSet com o resultado da consulta
     */
    public ResultSet Select(String sql, String nomeTela) {
        try {
            //ConnectDataBase(); futuro
            rs = null;
            PreparedStatement pst = conn.prepareStatement(sql);
            rs = pst.executeQuery();
        } catch (SQLException ex) {
            TratadorExecessaoController controlTratamentoErro = new TratadorExecessaoController();
            controlTratamentoErro.setErro(nomeTela, sql, ex.getMessage());
        } finally {
            //Desconectar(nomeTela); futuro
        }
        return rs;
    }

}
